#if !defined(MTX_DYNAMIC_H)
#define MTX_DYNAMIC_H

#include "mtx/types.h"	 
#include <cassert>
#include <vector>

namespace mtx {

class dynamic_vector_base {
public:
	typedef std::vector<double>::iterator iterator;
	typedef std::vector<double>::const_iterator const_iterator;
private:
	std::vector<double> _data;
public:
	dynamic_vector_base(size_type n = 0)
		: _data(n) { }
	size_type size() const
		{ return size_type(_data.size()); }
	const double & operator () (size_type i) const
		{ assert(i < size()); return _data[i]; }
	double & operator () (size_type i)
		{ assert(i < size()); return _data[i]; }
	const_iterator begin() const
		{ return _data.begin(); }
	const_iterator end() const
		{ return _data.end(); }
	iterator begin()
		{ return _data.begin(); }
	iterator end()
		{ return _data.end(); }
	void resize(size_type n)
		{ _data.resize(n); }
};

class dynamic_matrix_base {
public:
	typedef std::vector<double>::iterator iterator;
	typedef std::vector<double>::const_iterator const_iterator;
public:
	size_type _rows, _cols;
	std::vector<double> _data;
public:
	dynamic_matrix_base() 
		: _rows(0), _cols(0), _data() { }
	size_type rows() const
		{ return _rows; }
	size_type cols() const
		{ return _cols; }
	const double & operator () (size_type i, size_type j) const
		{ assert(i < _rows && j < _cols); return _data[i + j * _rows]; }
	double & operator () (size_type i, size_type j)
		{ assert(i < _rows && j < _cols); return _data[i + j * _rows]; }
	const_iterator begin() const
		{ return _data.begin(); }
	const_iterator end() const
		{ return _data.end(); }
	iterator begin()
		{ return _data.begin(); }
	iterator end()
		{ return _data.end(); }
	void resize(size_type m, size_type n)
		{ _data.resize((_rows = m) * (_cols = n)); }
};

struct dynamic {
public:
	typedef vector<dynamic_vector_base> vector;
	typedef matrix<dynamic_matrix_base> matrix;
};

} // mtx 

#endif // MTX_DYNAMIC_H
